#pragma once
#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cerrno>
#include "Comm.hpp"
#include "nocopy.hpp"
#include "Log.hpp"
#include "InetAddr.hpp"

//默认缺省值
static const std::string defaultip = "0.0.0.0";
static const uint16_t defaultport = 8888;
const static int defaltfd = -1;


class Udpserve : public nocopy
{
public:
    Udpserve(const uint16_t port = defaultport)
        :_port(port),_sockfd(defaltfd)
    {}
    void init()
    {
        _sockfd = socket(AF_INET,SOCK_DGRAM,0);//创建网络通信的文件 //udp来连接
        if(_sockfd < 0)
        {
            lg.LogMessage(Fatal,"Socket erro ,%d : %s",errno,strerror(errno));
            exit(socket_err);
        }
        lg.LogMessage(Info,"socket suceess,socket: %d\n",_sockfd);

        //绑定，网络信息
        struct sockaddr_in local;//基类
        bzero(&local ,sizeof(local));
        local.sin_family = AF_INET;//ip类型
        local.sin_port = htons(_port);//主机端口转为网络端口
        local.sin_addr.s_addr = INADDR_ANY;
        //local.sin_addr.s_addr = inet_addr(_ip.c_str());//变成网络序列


        int  n = ::bind(_sockfd,(struct sockaddr*)&local,sizeof(local));//：：避免名称冲突
        if(n!=0)
        {
            lg.LogMessage(Fatal,"bind erro ,%d : %s",errno,strerror(errno));
            exit(bind_erro);
        }
        //std::cout << "sucessful" << std::endl;

    }
    void start()
    {
        //服务器永远不退
        char buffer[1024];
        for(;;)
        {
            struct sockaddr_in peer;
            socklen_t len = sizeof(peer); 
            ssize_t n = recvfrom(_sockfd,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&peer,&len);
            if(n > 0)
            {
                InetAddr addr(peer);
        
                buffer[n] = 0;
                std::cout << addr.PrintDebug() << ": " << buffer <<std::endl;
                //buffer[n] = 0;
                sendto(_sockfd,buffer,strlen(buffer),0,(struct sockaddr*)&peer,len);
            }
        }
    }
    ~Udpserve()
    {
    }

private:
    std::string _ip;
    uint16_t _port;
    int _sockfd;
};
